using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ShareTools.Common;

namespace ShareTools.InfoPathFormsLib
{
    public class FormsFeatureManager
    {
        string _featuresFolder = @"Output\12\TEMPLATE\FEATURES";
        List<FormFeature> formsList = new List<FormFeature>();
        StringBuilder sb = new StringBuilder();

        public List<FormFeature> FormsList
        {
            get { return formsList; }
            set { formsList = value; }
        }

        public string FeaturesFolder
        {
            get { return _featuresFolder; }
            set { _featuresFolder = value; }
        }

        public FormsFeatureManager()
        {
            if (!Directory.Exists(FeaturesFolder))
            {
                Directory.CreateDirectory(FeaturesFolder);
            }
        }

        public string ProcessForms()
        {
            return ProcessForms(formsList);
        }

        public string ProcessForms(List<FormFeature> formsFeatureList)
        {
            foreach (FormFeature formInfo in formsFeatureList)
            {
                ProcessForm(formInfo);
            }
            return sb.ToString();
        }

        public string ProcessForm(FormFeature formFeature)
        {
            DirectoryInfo di = null;
            FileInfo fi = null;
            FileInfo dllfi = null;
            string cabPath = null;
            try
            {
                fi = new FileInfo(formFeature.FormPath);
                string thisFeatureFolder = Environment.CurrentDirectory + "\\" + FeaturesFolder + "\\" + formFeature.Title;
                sb.Append(fi.Name).Append(" - ");
                if (!Directory.Exists(thisFeatureFolder))
                {
                    di = Directory.CreateDirectory(thisFeatureFolder);
                }
                else
                    di = new DirectoryInfo(thisFeatureFolder);

                File.Copy(formFeature.FormPath, thisFeatureFolder + "\\" + fi.Name, true);

                if (formFeature.HasCodeBehind)
                {
                    if (string.IsNullOrEmpty(formFeature.DllPath))
                    {
                        cabPath = Environment.CurrentDirectory + "\\" + fi.Name.Replace("xsn", "cab");
                        //copy to local path while renaming it as a cab
                        if (formFeature.FormPath.EndsWith(".xsn"))// || zipFile.EndsWith(".XSN"))
                        {
                            File.Copy(formFeature.FormPath, cabPath, true);
                        }

                        //Extract the cab to get the DLL
                        ZipManager.UnzipPath = Environment.CurrentDirectory +"\\UnCabbed";
                        ZipManager.ExtractItems(cabPath);
                        File.Delete(cabPath);

                        string[] fileList = Directory.GetFiles(ZipManager.UnzipPath, "*.dll");
                        if(fileList.Length > 0)
                        foreach (string item in fileList)
                        {
                            formFeature.DllPath = item;
                        }
                    }

                    if (string.IsNullOrEmpty(formFeature.DllPath)) formFeature.HasCodeBehind = false;   //throw new Exception("DLL File is not found");
                    else
                    {
                        dllfi = new FileInfo(formFeature.DllPath);
                        File.Copy(formFeature.DllPath, thisFeatureFolder + "\\" + dllfi.Name, true);
                    }
                }
                sb.Append(formFeature.HasCodeBehind ? "Found code behind" : "No code behind").Append(" - ");
                StreamWriter sw = new StreamWriter(thisFeatureFolder +"\\"+ "elements.xml");
                sw.Write(GetElementsXML(formFeature));
                sw.Flush();
                sw.Close();

                sw = new StreamWriter(thisFeatureFolder + "\\" + "feature.xml");
                sw.Write(GetFeatureXML(formFeature));
                sw.Flush();
                sw.Close();
                sb.Append("Successed");                
            }
            catch (Exception ex)
            {
                sb.Append("Failed");
                throw  new Exception(ex.Message);
            }
            finally
            {
                try
                {
                    if (!string.IsNullOrEmpty(cabPath))
                        File.Delete(cabPath);
                    if (!string.IsNullOrEmpty(ZipManager.UnzipPath))
                        Directory.Delete(ZipManager.UnzipPath, true);
                }
                catch (Exception ex2)
                {
                }
            }
            sb.Append(Environment.NewLine);
            return sb.ToString();
        }

        public void RunWSPBuilder(string wspName)
        {
            //System.Diagnostics.Process.Start(Environment.CurrentDirectory + "\\Output\\WSPBuilder.exe");
            if (File.Exists(Environment.CurrentDirectory + "\\Output\\Output.wsp"))
                File.Delete(Environment.CurrentDirectory + "\\Output\\Output.wsp");
            if (File.Exists(Environment.CurrentDirectory + "\\Output\\solutionid.txt"))
                File.Delete(Environment.CurrentDirectory + "\\Output\\solutionid.txt");

            DirectoryInfo di = new DirectoryInfo(Environment.CurrentDirectory + "\\WSPBuilderLib");
            
            foreach (FileInfo fInfo in di.GetFiles())
            {
                fInfo.CopyTo(Path.Combine(Environment.CurrentDirectory + "\\Output", Path.GetFileName(fInfo.FullName)), true);
            }

            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.EnableRaisingEvents = false;
            proc.StartInfo.FileName = "ExecWSPBuilder.bat";
            proc.StartInfo.Arguments = wspName;
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.CreateNoWindow = true;
            proc.Start();
            proc.WaitForExit();

            di = new DirectoryInfo(Environment.CurrentDirectory + "\\Output");
            foreach (FileInfo fInfo in di.GetFiles())
            {
                if (!fInfo.Extension.Equals(".wsp") && !fInfo.Extension.Equals(".txt"))
                    File.Delete(fInfo.FullName);
            }
        }

        string GetElementsXML(FormFeature formInfo)
        {
            System.Text.StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version='1.0' encoding='utf-8' ?> ").Append(
                "<Elements xmlns='http://schemas.microsoft.com/sharepoint/'> ").Append(
                "<Module Name='XSN' Url='FormServerTemplates' RootWebOnly='TRUE'> ").Append(
                "<File Url='" + formInfo.FormPath.Substring(formInfo.FormPath.LastIndexOf(@"\")+1) + "' Name='" + formInfo.FormPath.Substring(formInfo.FormPath.LastIndexOf(@"\")+1) + "' Type='GhostableInLibrary'/> ").Append(
                "</Module> ").Append(
                "</Elements> ");
            return sb.ToString();
        }

        string GetFeatureXML(FormFeature formInfo)
        {
            System.Text.StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version='1.0' encoding='utf-8' ?>").Append(
                  "<Feature xmlns='http://schemas.microsoft.com/sharepoint/' ").Append(
                  "Id='" + formInfo.FeatureID.ToString().Replace("{", "").Replace("}", "") + "' ").Append(
                  "Title='"+ formInfo.Title +"' ").Append(
                  "Description='This feature deploys the browser enabled InfoPath Form.' ").Append(
                  "Version='12.0.0.0' ").Append(
                  "Scope='Site' ").Append(
                  "DefaultResourceFile='ipfscore' ").Append(
                  "ReceiverClass='Microsoft.Office.InfoPath.Server.Administration.XsnFeatureReceiver' ").Append(
                  "ReceiverAssembly='Microsoft.Office.InfoPath.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' > ").Append(
                  "<ActivationDependencies> ").Append(
                  "<ActivationDependency FeatureId='C88C4FF1-DBF5-4649-AD9F-C6C426EBCBF5'/> ").Append(
                  "</ActivationDependencies> ").Append(
                  "<ElementManifests> ").Append(
                  "<ElementManifest Location='elements.xml'/> ").Append(
                  "<ElementFile Location='"+ formInfo.FormPath.Substring(formInfo.FormPath.LastIndexOf(@"\")+1) +"'/> ");
            
            if(formInfo.HasCodeBehind)
                sb.Append("<ElementFile Location='" + formInfo.DllPath.Substring(formInfo.DllPath.LastIndexOf(@"\")+1) + "' /> ");

                  sb.Append("</ElementManifests> ").Append(
                  "<Properties> ").Append(
                  "<Property Key='FeatureName' Value='InfoPath Form Template Feature'/> ").Append(
                  "</Properties> ").Append(
                  "</Feature>");

                  return sb.ToString();
        }
    }
}
